在本系列文中,所有的程式碼以及測試都可以在 should-i-use-fp-ts 找到,今日的範例放在 src/day-15
並且有習題和測試可以讓大家練習。
昨天學習了 O.Do
以及 O.bind
,但使用起來有點繁瑣。
// use x = 2 as example
const verbose = (x: number) => pipe(
O.Do, // { _tag: 'Some', value: {} }
O.bind('x', () => O.of(x)), // { _tag: 'Some', value: { x: 2 } }
);
上述兩行中有實際邏輯意義的部分只有 O.bind('x', () => O.of(x))
,這個部分有點像是之前的 O.map
+ O.flatten
,這種行為可以另外設計一個函數來簡化,讓 pipe
中的邏輯更加精粹。
這邊開始實作 bindTo
,一樣先從型別開始定義。
type BindTo = <N extends string>(name: N) => <A>(fa: O.Option<A>) => O.Option<{ readonly [K in N]: A }>;
bindTo
和 bind
非常類似,一樣是先傳入 property
的名稱,之後傳入要注入這個 property
的生成函式。
接著定義 bindTo
的行為。
const bindTo: BindTo = name => fa => pipe(
fa,
O.map(a => ({ [name]: a } as any)),
);
由於使用 bindTo
的情境是沒有 Do
的,所以函式行為比 bind
更單純,將 fa
運算結果放入 Option<Object>
即可。
以下是實際使用的範例。
// use x = 2 as example
export const simple = (x: number) => pipe(
O.of(x), // { _tag: 'Some', value: 2 }
O.bindTo('x'), // { _tag: 'Some', value: { x: 2 } }
);
如此一來,pipe
之中只含有重要的訊息。
x
轉入 Option
的領域。x
之中。不再有雞肋的 O.Do
佔領版面,整個 pipe
變的更加簡要。
今天的主題在 should-i-use-fp-ts src/day-15
有習題和測試可以練習,大家可以嘗試自己能不能寫出自己的 bindTo
。